package com.example.fashion.android.view;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @Description:
 * @author
 * @date 2016年3月18日 上午9:20:41
 */

/**
 * A basic Camera preview class
 */
public class CameraPreview extends SurfaceView
        implements SurfaceHolder.Callback {


    /**
     * 监听接口
     */
    private OnCameraStatusListener listener;

    private SurfaceHolder holder;
    private Camera mCamera;
    private int mCameraPosition = 1;//0代表前置摄像头，1代表后置摄像头

    private Point screenResolution;


    // 创建一个PictureCallback对象，并实现其中的onPictureTaken方法
    private PictureCallback pictureCallback = new PictureCallback() {

        // 该方法用于处理拍摄后的照片数据
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {

            //释放相机
            releaseCamera();

            // 调用结束事件
            if (null != listener) {
                listener.onCameraStopped(data, mCameraPosition);
            }
        }
    };
    private PictureCallback rawCallback = new PictureCallback() {
        public void onPictureTaken(byte[] _data, Camera _camera) {
            /* 要处理raw data?写?否 */
        }
    };
    /*为了实现拍照的快门声音及拍照保存照片需要下面三个回调变量*/
    ShutterCallback myShutterCallback = new ShutterCallback()
            //快门按下的回调，在这里我们可以设置类似播放“咔嚓”声之类的操作。默认的就是咔嚓。
    {

        public void onShutter() {
            // TODO Auto-generated method stub

        }
    };

    // Preview类的构造方法
    public CameraPreview(Context context, AttributeSet attrs) {
        super(context, attrs);
        // 获得SurfaceHolder对象
        holder = getHolder();
        // 指定用于捕捉拍照事件的SurfaceHolder.Callback对象
        // 只要是实现SurfaceHolder.Callback接口的对象都行
        holder.addCallback(this);
        // 设置SurfaceHolder对象的类型
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    // 在surface创建时激发
    public void surfaceCreated(SurfaceHolder holder) {
        try {
            initCamera();
            if (null != listener) {
                listener.onTouchFocus(mCamera);
            }
        } catch (IOException e) {
            e.printStackTrace();
            // 释放手机摄像头
            mCamera.release();
            mCamera = null;
        }
    }

    // 在surface销毁时激发
    public void surfaceDestroyed(SurfaceHolder holder) {
        // Log.e(TAG, "==surfaceDestroyed==");
        if (mCamera != null) {
            mCamera.setPreviewCallback(null); /*在启动PreviewCallback时这个必须在前不然退出出错。
                       这里实际上注释掉也没关系*/

            mCamera.stopPreview();
            // 释放手机摄像头
            mCamera.release();
        }
    }

    // 在surface的大小发生改变时激发
    public void surfaceChanged(final SurfaceHolder holder, int format, int w, int h) {


    }

    /**
     * @throws IOException
     */
    protected void initCamera() throws IOException {
        // 获得Camera对象
        mCamera = Camera.open();
        // 设置用于显示拍照摄像的SurfaceHolder对象
        mCamera.setPreviewDisplay(holder);
        // 获取照相机参数
        Camera.Parameters parameters = mCamera.getParameters();
        // 设置照片格式
        parameters.setPictureFormat(PixelFormat.JPEG);

        //parameters.setFlashMode(Parameters.FLASH_MODE_TORCH);//加上闪光灯模式会报错
        // 1连续对焦
        parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);


        //获得手机支持的尺寸
        List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes();
        List<Camera.Size> pictureSizes = parameters.getSupportedPictureSizes();
        //获得屏幕大小
        DisplayMetrics dm2 = getResources().getDisplayMetrics();
        screenResolution = new Point(dm2.widthPixels, dm2.heightPixels);
        // preview size is always something like 480*320, other 320*480
        Point screenResolutionForCamera = new Point();
        screenResolutionForCamera.x = screenResolution.x;
        screenResolutionForCamera.y = screenResolution.y;


        //获得最佳的图片大小
        Camera.Size previewSize = getBestSize(1.3, previewSizes, screenResolutionForCamera.y, screenResolutionForCamera.x);
        Camera.Size pictureSize = getBestSize(1.3, pictureSizes);

        parameters.setPreviewSize(previewSize.width, previewSize.height);
        parameters.setPictureSize(pictureSize.width, pictureSize.height);

        //设置显示方向
        setCameraOrientation(mCamera, mCameraPosition);

        // 设置照相机参数
        mCamera.setParameters(parameters);
        // 开始拍照
        mCamera.startPreview();
        mCamera.cancelAutoFocus();// 一定要加上这句，才可以连续聚集
    }

    // 停止拍照，并将拍摄的照片传入PictureCallback接口的onPictureTaken方法
    public void takePicture(boolean isAutoFocus) {
        // Log.e(TAG, "==takePicture==");
        if (mCamera != null) {
            if (isAutoFocus) {
                // 自动对焦
                mCamera.autoFocus(new AutoFocusCallback() {
                    @Override
                    public void onAutoFocus(boolean success, Camera camera) {
                        if (null != listener) {
                            listener.onAutoFocus(success);

                        }
                        // 自动对焦成功后才拍摄
                        if (success) {
                            camera.takePicture(myShutterCallback, rawCallback, pictureCallback);
                        }
                    }
                });
            } else {
                mCamera.takePicture(myShutterCallback, rawCallback, pictureCallback);
            }
        }
    }

    /**
     * 获得最佳的图片大小
     *
     * @param sizeScale
     * @param SizeList
     * @param width
     * @param height
     * @return
     */
    public Camera.Size getBestSize(double sizeScale, List<Camera.Size> SizeList, int width, int height) {

        Camera.Size bigSize = null;
        double l = sizeScale - 0.1;
        double u = sizeScale + 0.1;

        List<Camera.Size> newPreviewSizes = new ArrayList<>();
        for (Camera.Size previewSize : SizeList) {
            double w = (double) previewSize.width;
            double h = (double) previewSize.height;
            if (l < w / h && w / h < u && (w + h) <= (width + height)) {
                newPreviewSizes.add(previewSize);
            }
        }

        if (newPreviewSizes.size() > 0) {
            for (Camera.Size size : newPreviewSizes) {
                if (bigSize == null) {
                    bigSize = size;
                    continue;
                } else {
                    if ((size.width + size.height) > (bigSize.width + bigSize.height)) {
                        bigSize = size;
                    }
                }
            }
        }
        return bigSize;

    }

    /**
     * 获得最佳的图片大小
     *
     * @param sizeScale
     * @param SizeList
     * @return
     */
    public Camera.Size getBestSize(double sizeScale, List<Camera.Size> SizeList) {

        Camera.Size bigSize = null;
        double l = sizeScale - 0.1;
        double u = sizeScale + 0.1;

        List<Camera.Size> newPreviewSizes = new ArrayList<>();
        for (Camera.Size previewSize : SizeList) {
            double w = (double) previewSize.width;
            double h = (double) previewSize.height;
            if (l < w / h && w / h < u) {
                newPreviewSizes.add(previewSize);
            }
        }

        if (newPreviewSizes.size() > 0) {
            for (Camera.Size size : newPreviewSizes) {
                if (bigSize == null) {
                    bigSize = size;
                    continue;
                } else {
                    if ((size.width + size.height) > (bigSize.width + bigSize.height)) {
                        bigSize = size;
                    }
                }
            }
        }
        return bigSize;

    }


    // 设置监听事件
    public void setOnCameraStatusListener(OnCameraStatusListener listener) {
        this.listener = listener;
    }

    /**
     * 相机拍照监听接口
     */
    public interface OnCameraStatusListener {

        // 相机拍照结束事件
        void onCameraStopped(byte[] data, int mameraPosition);

        // 拍摄时自动对焦事件
        void onAutoFocus(boolean success);

        // 触摸屏幕对焦事件
        void onTouchFocus(Camera mCamera);
    }

    /**
     * 切换摄像头
     */
    @SuppressLint("NewApi")
    public void switchCamera() {
        //切换前后摄像头
        int cameraCount;
        CameraInfo cameraInfo = new CameraInfo();
        cameraCount = Camera.getNumberOfCameras();//得到摄像头的个数

        for (int i = 0; i < cameraCount; i++) {
            Camera.getCameraInfo(i, cameraInfo);//得到每一个摄像头的信息
            if (mCameraPosition == 1) {
                //现在是后置，变更为前置
                if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {//代表摄像头的方位，CAMERA_FACING_FRONT前置      CAMERA_FACING_BACK后置
                    mCamera.stopPreview();//停掉原来摄像头的预览
                    mCamera.release();//释放资源
                    mCamera = null;//取消原来摄像头
                    mCamera = Camera.open(i);//打开当前选中的摄像头
                    try {
                        mCamera.setPreviewDisplay(holder);//通过surfaceview显示取景画面

                        //设置显示方向
                        setCameraOrientation(mCamera, mCameraPosition);

                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    mCamera.startPreview();//开始预览
                    mCameraPosition = 0;
                    break;
                }
            } else {
                //现在是前置， 变更为后置
                if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {//代表摄像头的方位，CAMERA_FACING_FRONT前置      CAMERA_FACING_BACK后置
                    mCamera.stopPreview();//停掉原来摄像头的预览
                    mCamera.release();//释放资源
                    mCamera = null;//取消原来摄像头
                    mCamera = Camera.open(i);//打开当前选中的摄像头
                    try {
                        mCamera.setPreviewDisplay(holder);//通过surfaceview显示取景画面

                        //设置显示方向
                        setCameraOrientation(mCamera, mCameraPosition);

                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    mCamera.startPreview();//开始预览
                    mCameraPosition = 1;
                    break;
                }
            }

        }
    }

    /**
     * 设置相机显示方向
     * （后置摄像头旋转90度，前置摄像头需旋转180度）
     *
     * @param camera
     * @param cameraPosition
     */
    public void setCameraOrientation(Camera camera, int cameraPosition) {
        if (cameraPosition == Camera.CameraInfo.CAMERA_FACING_BACK) {
            camera.setDisplayOrientation(90);
        } else {
            camera.setDisplayOrientation(90);
        }
    }

    /**
     * 设置闪光灯
     */
    public void toogleFlash() {
        Camera.Parameters parameters = mCamera.getParameters();
        if (parameters.getFlashMode().equals(Camera.Parameters.FLASH_MODE_OFF)) {
            parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
        } else {
            parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
        }
        mCamera.setParameters(parameters);
    }

    /**
     * 释放相机
     */
    public void releaseCamera() {
        if (mCamera != null) {
            mCamera.setPreviewCallback(null);
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
        }
    }
}